﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Converters;
using GroupCheer.FBGraphAPI.Core;

namespace GroupCheer.FBGraphAPI.API
{
    public class SearchPaging<T, TCollection> where TCollection : ICollection<T>
    {
        public string PreviousPagingUrl { get; protected set; }
        public string NextPagingUrl { get; protected set; }
        public TCollection LastResult { get; protected set; }

        public bool Load(string LoadUrl) 
        {
            string jsonResponse = Network.MakeHttpGet(LoadUrl);
            TCollection collection = (TCollection)Activator.CreateInstance(typeof(TCollection));

            JObject jsonObject = JObject.Parse(jsonResponse);

            if (jsonObject.SelectToken("data").Children().Count() > 0)
            {
                JToken dataNode = jsonObject.SelectToken("data");

                foreach (JToken token in dataNode.Children())
                {
                    T item = (T)Activator.CreateInstance(typeof(T));
                    PropertyInfo[] properties = item.GetType().GetProperties();

                    foreach (PropertyInfo property in properties)
                    {
                        if (property.Name == "PosterID")
                            property.SetValue(item, (token.SelectToken("from").SelectToken("id") as JValue).Value, null);
                        if (property.Name == "PosterName")
                            property.SetValue(item, (token.SelectToken("from").SelectToken("name") as JValue).Value, null);
                        else
                        {
                            if (token.SelectToken(property.Name.ToLower()) != null)
                                property.SetValue(item, (token.SelectToken(property.Name.ToLower()) as JValue).Value, null);
                        }
                    }

                    collection.GetType().GetMethod("Add").Invoke(collection, new object[] { item });
                }
            }

            // find paging url.
            if (jsonObject.SelectToken("paging") != null)
            {
                JToken jsonNextPageUrl = jsonObject.SelectToken("paging").SelectToken("next");
                JToken jsonPreviousPageUrl = jsonObject.SelectToken("paging").SelectToken("previous");

                if (jsonNextPageUrl != null)
                    this.NextPagingUrl = (jsonNextPageUrl as JValue).Value.ToString();
                else
                    this.NextPagingUrl = null;

                if (jsonPreviousPageUrl != null)
                    this.PreviousPagingUrl = (jsonPreviousPageUrl as JValue).Value.ToString();
                else
                    this.PreviousPagingUrl = null;
            }

            this.LastResult = collection;

            return (collection.Count > 0);                
        }

        public bool HasNextPage { get { return (!string.IsNullOrEmpty(this.NextPagingUrl)); } }
        public bool HasPrevPage { get { return (!string.IsNullOrEmpty(this.PreviousPagingUrl)); } }

        public bool GoNextPage()
        {
            if (string.IsNullOrEmpty(this.NextPagingUrl))
                return false;

            return this.Load(this.NextPagingUrl);
        }

        public bool GoPrevPage()
        {
            if (string.IsNullOrEmpty(this.NextPagingUrl))
                return false;

            return this.Load(this.PreviousPagingUrl);
        }
    }
}
